//
//  list_head.h
//  Job_Scheduling
//
//  Created by zhangyukun on 2021/4/21.
//

#ifndef list_head_h
#define list_head_h

#include <stdbool.h>

/*
This head file'usage is what I have learned from "list.h" in linux' kernel
and "los_list.h" in harmony OS's kernel .
**/

//struct list_head is to link different JCB and contitute wait_list and ready_list .
struct list_head{
    struct list_head *prev;
    struct list_head *next;
};

//create a new struct list_head and initialize it .
#define LIST_HEAD_INIT(name) {&(name),&(name)}
#define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name)
#define INIT_LIST_HEAD(ptr) do{\
                            (ptr)->prev = (ptr);\
                            (ptr)->next = (ptr);\
                            }while(0)
//it is to help find the start address of one struct that includes struct list_head .
#define list_entry(ptr,type,member) (type*)((char*)(ptr) - (unsigned long)(&((type*)0)->member))
//tranverse the double-linked circular list .
#define list_for_each(ptr,head) for((ptr) = (head)->next;(ptr) != (head);(ptr) = (ptr)->next)

static void inline __add_list(struct list_head *node,struct list_head *prev,struct list_head *next);
static void inline __del_list(struct list_head *prev,struct list_head *next);
static void add(struct list_head *pos,struct list_head *node);
static void del(struct list_head *node);
static bool is_empty(struct list_head *head);

//it is an auxiliary function .
static void inline __add_list(struct list_head *node,struct list_head *prev,struct list_head *next){
    node->next = next;
    node->prev = prev;
    prev->next = node;
    next->prev = node;
}
//it is an auxiliary function .
static void inline __del_list(struct list_head *prev,struct list_head *next){
    prev->next = next;
    next->prev = prev;
}
//call auxiliary function __add_list to add one node to certain position of this double-linked circular list .
static void add(struct list_head *pos,struct list_head *node){
    __add_list(node, pos, pos->next);
}
//call auxiliary function __del_list to delete one node from one double-linked circular list .
static void del(struct list_head *node){
    __del_list(node->prev, node->next);
}
//test whether the double-linked circular list is empty .
static bool is_empty(struct list_head *head){
    return  head == head->next;
}
#endif /* list_head_h */
